package co.yixiang.mall.biz.commission.service.impl;

import co.yixiang.mall.biz.commission.mapper.*;
import co.yixiang.mall.biz.commission.service.RebateService;
import co.yixiang.mall.biz.entity.YxCommissionGiveOutRecord;
import co.yixiang.mall.biz.entity.YxUserIntegralDetails;
import co.yixiang.mall.biz.freeze.mapper.TbUserRebateFreezeMapper;
import co.yixiang.mall.biz.mallsetting.mapper.TbBrokerageFreezeMapper;
import co.yixiang.mall.common.mall.domain.YxUser;
import co.yixiang.mall.common.mallsetting.domain.TbBrokerageFreeze;
import co.yixiang.mall.common.order.domain.TbUserRebateFreeze;
import co.yixiang.mall.common.order.domain.YxStoreOrder;
import co.yixiang.mall.common.product.domain.YxStoreProduct;
import co.yixiang.mall.common.shop.domain.YxSystemUserLevel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

@Log4j2
@Service
public class RebateServiceImpl implements RebateService {

    @Autowired
    YxUserService userMapper;

    @Autowired
    CommissionService commissionService;

    @Autowired
    LevelService levelService;

    @Autowired
    IntegralDetailsService details;

    @Autowired
    GiveOutRecordService giveOutRecordService;

    @Autowired
    StoreProductService product;

    @Autowired
    OrderCartInfoService cartInfo;

    @Autowired
    TbBrokerageFreezeMapper freezeMapper;

    @Autowired
    TbUserRebateFreezeMapper rebateFreezeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer closeAccount() {
        /** 将用户表中数据全部拿出 */
        List<YxUser> yxUsers = userMapper.selectList(null);
        for(YxUser x : yxUsers){
            x = upDataUser(x);
            /** 根据用户查询所有订单信息 */
            QueryWrapper wrapper1 = new QueryWrapper();
            wrapper1.eq("uid",x.getUid());// 用户id查询
            wrapper1.eq("freeze",1);// 订单必须解冻
            wrapper1.eq("refund_status",0); // 退款必须是未退款
            wrapper1.eq("status",3);// 订单状态必须是已完成
            List<YxStoreOrder> orderList = commissionService.selectList(wrapper1);
            for(YxStoreOrder order : orderList){
                /** 获得订单的返利积分 */
                BigDecimal freezeIntegral = order.getFreezeIntegral();
                /** 获得订单的返利金额 */
                BigDecimal freezeMoney = order.getFreezeMoney();
                YxUser yxUser = new YxUser();
                if(freezeIntegral.compareTo(new BigDecimal(0)) == 1){
                    YxUserIntegralDetails integralDetails = new YxUserIntegralDetails();
                    integralDetails.setOid(order.getId());
                    integralDetails.setIntegral(freezeIntegral);
                    integralDetails.setUid(x.getUid());
                    details.insert(integralDetails);
                }
                YxCommissionGiveOutRecord record = new YxCommissionGiveOutRecord();
                record.setOid(order.getId());
                record.setUid(x.getUid());
                record.setType(1);
                record.setGrantMoney(freezeMoney);
                giveOutRecordService.insert(record);

                /** 将月结用户表中的佣金减去 */
                QueryWrapper select = new QueryWrapper();
                select.eq("uid",x.getUid());
                select.eq("clearing",1);
                TbBrokerageFreeze tbBrokerageFreeze = freezeMapper.selectOne(select);
                BigDecimal money = tbBrokerageFreeze.getBuyRebate().subtract(freezeMoney);
                BigDecimal integral = tbBrokerageFreeze.getFreezingIntegral().subtract(freezeIntegral);
                BigDecimal bigDecimal = new BigDecimal("0.0");
                if(!(money.compareTo(bigDecimal) == -1)){// 未结算佣金减去订单佣金大于等于0时将修改
                    tbBrokerageFreeze.setBuyRebate(money);
                }else if(!(integral.compareTo(bigDecimal) == -1)){// 未结算积分减去订单积分大于等于0时修改
                    tbBrokerageFreeze.setFreezingIntegral(integral);
                }else{
                    log.error("结算时佣金或积分减去订单佣金或积分小于0");
                }
                freezeMapper.updateById(tbBrokerageFreeze);

                /** 将日结用户表中的订单设为已发放 */
                TbUserRebateFreeze rebateFreeze = new TbUserRebateFreeze();
                rebateFreeze.setState(2);
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("user_id",x.getUid());
                queryWrapper.eq("order_id",order.getId());
                rebateFreezeMapper.update(rebateFreeze,queryWrapper);

                yxUser.setIntegral(x.getIntegral().add(freezeIntegral));
                yxUser.setNowMoney(x.getNowMoney().add(freezeMoney));
                QueryWrapper wrapper = new QueryWrapper();
                wrapper.eq("uid",x.getUid());
                /** 更新数据库添加用户的金额 */
                userMapper.update(yxUser,wrapper);
            }

        };
        return 0;
    }

    @Override
    /** 当订单确认收货时执行的方法 */
    public Integer upDataOrder(YxStoreOrder order, Timestamp startTime,Timestamp endTime){
        Integer type = 0;
        BigDecimal ratio = new BigDecimal("0.1");
        BigDecimal integralRatio = new BigDecimal("1.5");


        YxUser x = userMapper.selectById(order.getUid());
        x = upDataUser(x);
        /** 根据用户等级查询用户的复销封顶 */
        YxSystemUserLevel level = levelService.selectById(x.getLevel());
        if(level == null){
            return 3;// 该用户为普通会员 不参与自购返利
        }
        BigDecimal capping = level.getCapping();
        BigDecimal capping1 = x.getCapping();
        boolean isCapping = false;
        /** 判断用户扣除的金额是否达到复销封顶 */
        if(/** 本月复销未封顶 */capping.compareTo(capping1) == 1){
            isCapping = true;
        }else if(/** 用户本月复销扣除以封顶 */capping.compareTo(capping1) == 0){
            isCapping = false;
        }
        /** 订单复消 */
        /** 查询订单中所有参加累计的商品 */
        YxStoreProduct product1 = product.queryProduct(order.getId(),1);
        if(product1 == null){
            return 4;// 该商品不参加返利
        }
        /** 该订单复消金额 consume = consume + (获取商品的pv值 * 实付金额 得到该商品的复消金额) */
        BigDecimal consume = product1.getPvValue().multiply(order.getPayPrice());

        /** 该订单自购返利应获得的金额 */
        BigDecimal multiply = consume.multiply(level.getCommissionRatio());
        /** 本单转换的积分 */
        BigDecimal integral = new BigDecimal("0.0");
        if(isCapping){
            /** 减去的金额 */
            BigDecimal money = multiply.multiply(ratio);
            /** 获取他的积分 */
            integral = money.multiply(integralRatio);
            if(capping1.add(money).compareTo(capping) < 1){
                /** 本月转换积分没超出 */
                capping1 = capping1.add(money);
                /** 扣除0分用户真正获得的金额 */
                multiply = multiply.subtract(money);
                type = 0;// 该用户的本月转换积分未封顶
            }else if(capping1.add(money).compareTo(capping) == 1){
                /** 本月金额加起来就超出了*/
                BigDecimal subtract = capping1.add(money).subtract(capping);
                capping1 = capping1.add(subtract);
                multiply = multiply.subtract(money.subtract(subtract));
                integral = subtract.multiply(integralRatio);
                type = 1;// 该用户本月转换积分以封顶
            }
        }
        /** 将该订单金额放进月冻结表中 */
        QueryWrapper select = new QueryWrapper();
        select.eq("uid",x.getUid());
        select.eq("clearing",0);
        TbBrokerageFreeze tbBrokerageFreeze = freezeMapper.selectOne(select);
        tbBrokerageFreeze.setBuyRebate(tbBrokerageFreeze.getBuyRebate().add(multiply));
        tbBrokerageFreeze.setFreezingIntegral(tbBrokerageFreeze.getFreezingIntegral().add(integral));
        freezeMapper.updateById(tbBrokerageFreeze);

        /** 将该订单金额放进日冻结表中 */
        TbUserRebateFreeze freeze = null;
        if(startTime != null && endTime != null){
            freeze = new TbUserRebateFreeze();
            freeze.setUserId(Integer.parseInt(String.valueOf(x.getUid())));
            freeze.setCommissionType("1");
            freeze.setState(1);
            freeze.setAccumulativeAmount(new BigDecimal("0.0"));
            freeze.setOrderId(Integer.parseInt(String.valueOf(order.getId())));
        }else{
            QueryWrapper freezeQuery = new QueryWrapper();
            freezeQuery.eq("user_id",x.getUid());
            freezeQuery.eq("order_id",order.getId());
            freeze = rebateFreezeMapper.selectOne(freezeQuery);
        }
        freeze.setMoney(multiply);
        freeze.setScore(integral);
        rebateFreezeMapper.insert(freeze);

        /** 更新订单表 */
        YxStoreOrder storeOrder = new YxStoreOrder();
        storeOrder.setFreezeIntegral(integral);
        storeOrder.setFreezeMoney(multiply);
        storeOrder.setConsumptionResults(consume);
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("id",order.getId());
        commissionService.update(storeOrder,wrapper);
        x.setCapping(capping1);
        userMapper.updateById(x);
        return type;
    }

    /** 退货时调用的方法 */
    public Integer deleteOrder(Long orderId){
        YxStoreOrder order = commissionService.selectById(orderId);
        if(!(order.getFreezeIntegral().compareTo(new BigDecimal("0.0")) == 1)){
            return 1;
        }
        YxUser user = userMapper.selectById(order.getUid());
        user = upDataUser(user);
        BigDecimal integral = order.getFreezeIntegral();
        BigDecimal money = integral.divide(new BigDecimal("1.5"));

        /** 将月结订单表中的用户冻结总佣金减去 */
        QueryWrapper select = new QueryWrapper();
        select.eq("uid",user.getUid());
        select.eq("clearing",1);
        TbBrokerageFreeze tbBrokerageFreeze = freezeMapper.selectOne(select);
        BigDecimal money1 = tbBrokerageFreeze.getBuyRebate().subtract(money);
        BigDecimal integral1 = tbBrokerageFreeze.getFreezingIntegral().subtract(integral);
        BigDecimal bigDecimal = new BigDecimal("0.0");
        if(!(money1.compareTo(bigDecimal) == -1)){// 未结算佣金减去订单佣金大于等于0时将修改
            tbBrokerageFreeze.setBuyRebate(money1);
        }else if(!(integral1.compareTo(bigDecimal) == -1)){// 未结算积分减去订单积分大于等于0时修改
            tbBrokerageFreeze.setFreezingIntegral(integral1);
        }else{
            log.error("结算时佣金或积分减去订单佣金或积分小于0");
        }
        freezeMapper.updateById(tbBrokerageFreeze);

        /** 将日结用户表中的订单设为已取消 */
        TbUserRebateFreeze rebateFreeze = new TbUserRebateFreeze();
        rebateFreeze.setState(3);
        QueryWrapper queryWrapper1 = new QueryWrapper();
        queryWrapper1.eq("user_id",user.getUid());
        queryWrapper1.eq("order_id",order.getId());
        rebateFreezeMapper.update(rebateFreeze,queryWrapper1);

        YxUser yxUser = new YxUser();
        yxUser.setCapping(user.getCapping().subtract(money));
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("uid",user.getUid());// 用户id查询
        wrapper.eq("freeze",1);// 订单必须解冻
        wrapper.eq("refund_status",0); // 退款必须是未退款
        wrapper.eq("status",3);// 订单状态必须是已完成
        wrapper.gt("freeze_integral",0);// 该订单必须是没有没有积分的
        List<YxStoreOrder> orderList = commissionService.selectList(wrapper);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("uid",user.getUid());
        userMapper.update(yxUser,queryWrapper);
        for(YxStoreOrder storeOrder: orderList){
            Integer integer = this.upDataOrder(storeOrder,null,null);
            if(integer==1){
                break;
            }
        }
        return 0;

    }
    public YxUser upDataUser(YxUser x){
        /** 使用之前先去更新用户本月以扣除转换积分金额 */
        QueryWrapper userQuery = new QueryWrapper();
        userQuery.eq("uid",x.getUid());
        userQuery.eq("clearing",0);
        List<TbBrokerageFreeze> freezes = freezeMapper.selectList(userQuery);
        /** 本月扣除金额 */
        BigDecimal big = new BigDecimal("0.0");
        for(TbBrokerageFreeze rebateFreeze : freezes){
            big = big.add(rebateFreeze.getFreezingIntegral());
        }
        big.divide(new BigDecimal("1.5"));
        x.setCapping(big);
        userMapper.updateById(x);
        return x;
    }
}
